﻿using Client;
using Seagull.BarTender.Print;
using Shared.Method;
using Shared.Model;
using StationClient.Dialog;
//using StationClient.HelpClass;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace StationClient
{
    public partial class FormBox : Form
    {
        private FormStation _formSta = null;//上一个界面
        private STATION _sta = null;//当前工位信息
        private List<PROCESS> _listProcess = null;//保存过程信息
        private List<PRODUCT> _listProduct = null;//保存产品信息

        private List<Device_Data> _listData = null;//保存光猫信息
        private List<PRODUCT_SN> _listSn = null;//保存SN信息

        private List<Device_Type> _listDeviceType = null;//保存产品类型信息

        //打标的信息
        private string _btwPath = null;

        //型号和省份信息
        private string _deviceType = null;
        private string _province = null;

        private string _btwQuery = "查询提示1";

        private int _btwCopies = 2;
        private long _lastSnNum = 0;

        private readonly string DATA_DIR = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "DATA\\";//保存包装数据

        public FormBox(FormStation formSta, STATION sta)
        {
            _sta = sta;
            _formSta = formSta;
            _listProcess = new List<PROCESS>();
            _listProduct = new List<PRODUCT>();
            _listData = new List<Device_Data>();
            _listSn = new List<PRODUCT_SN>();

            //打印份数
            int copies = 0;
            if (int.TryParse(AppSetting.GetValue("BtwCopyes"), out copies))
            {
                _btwCopies = copies;
            }
            else
            {
                MessageBox.Show("获取打印份数失败");
            }

            string query = AppSetting.GetValue("BtwQueryName");
            if (string.IsNullOrEmpty(query) == false) _btwQuery = query;
            InitializeComponent();
        }

        //SN包装
        private void textBoxProductSN_KeyPress(object sender, KeyPressEventArgs e)
        {
            //只能输入16进制数字和回车符号'\r'或者'\n'，MAC地址中的字符只能位0-9,A~F
            if (e.KeyChar == '\n' || e.KeyChar == '\r')
            {
                Action actStart = new Action(BoxStart);//异步装箱操作，让输出完整
                actStart.BeginInvoke(null, null);
                e.Handled = true;
            }
            else if ((e.KeyChar >= 'a' && e.KeyChar <= 'f')
                || (e.KeyChar >= 'A' && e.KeyChar <= 'F')
                || (e.KeyChar >= '0' && e.KeyChar <= '9')
                || (e.KeyChar == 8))
            {
                //判断是否位16进制字符，将小写全部转为大写
                e.Handled = false;
            }
            else
            {
                MessageBox.Show("只能输入数字和A-F");
                e.Handled = true;
            }
        }

        //判断产品能否装箱
        private void BoxStart()
        {
            SetTextBoxSnEnable(false);

            string strSn = this.textBoxProductSN.Text.ToUpper().Trim();

            if (strSn.Length == 12)//扫描MAC
            {
                Device_Data deviceW = new Device_Data();
                deviceW.SetWhere();
                deviceW.MACAddr = strSn;
                var selectProSn = MethodWcf.SelectDeviceDataClient(deviceW);
                if (selectProSn.result)
                {
                    strSn = selectProSn.value[0].SN;
                }
            }

            //判断SN是否为18位
            if (string.IsNullOrEmpty(strSn) || strSn.Length != 18)
            {
                MessageBox.Show("SN不为18位字符串");
                SetFocusSN();
                return;
            }

            long.TryParse(strSn.Substring(strSn.Length - 6), out long snNum);

            //check the sn number sorted or not
            if (_lastSnNum == 0 && snNum % 20 == 1)
            {
                _lastSnNum = snNum;
            }
            else if (_lastSnNum != 0 && snNum - _lastSnNum == 1)
            {
                _lastSnNum = snNum;
            }
            else
            {
                AppendRichTextBox("SN号码不连贯，请扫描正确的SN");
                SetFocusSN();
                return;
            }

            if (_listSn.Count == 0)//如果是开始扫描的时候，将显示箱号的地方置为空
            {
                SetBoxNo(string.Empty);

                //根据MAC查到所有的DEVICE DATA 和 SN
                if (GetAllMessage(strSn) == false)
                {
                    SetFocusSN();
                    return;
                }

                //获取配置数据
                if (_deviceType != _listData[0].DeviceType || _province != _listData[0].HW_PROVINCE_NAME)
                {
                    _btwPath = AppSetting.GetValue(string.Format("{0}_{1}_1", _listData[0].DeviceType, _listData[0].HW_PROVINCE_NAME));

                    if (string.IsNullOrEmpty(_btwPath)) _btwPath = AppSetting.GetValue(string.Format("{0}_1", _listData[0].DeviceType));
                }
            }

            //判断SN是否在LISTSN当中
            var product_sn = (from s in _listSn
                              where s.FULL_PRODUCT_SN == strSn
                              select s).FirstOrDefault();

            if (product_sn == null)
            {
                AppendRichTextBox(string.Format("SN[{0}]不在箱子[{1}]当中，请检查！", strSn, _listSn[0].FULL_BOX_SN));
                SetFocusSN();
                return;
            }

            //判断MAC是否在_listPRODUCT中
            var product = (from p in _listProduct
                           where p.MAC == product_sn.MAC
                           select p).FirstOrDefault();

            if (product != null)
            {
                AppendRichTextBox(string.Format("请勿重复扫描SN[{0}]", strSn));
                SetFocusSN();
                return;
            }

            //判断能否进行下一道工序
            StartRequest request = new StartRequest()
            {
                PRODUCT_MAC = product_sn.MAC,
                STATION_MAC = _sta.MAC
            };

            AppendRichTextBox("申请包装……");
            var canStart = MethodWcf.CanStartClient(request);

            //可以进行此道工序
            AppendRichTextBox(string.Format("申请结果[{0}]，SN[{1}]", canStart.message, strSn));
            if (!canStart.result)//不能进行此道工序
            {
                SetFocusSN();
                return;
            }

            //写product
            product = new PRODUCT();
            product.SetWhere();
            product.MAC = product_sn.MAC;
            product.SetUpdate();
            product.TEST_RESULT = "Y";
            product.FLOW_ID = _sta.FLOW_ID;
            product.LINE_ID = _sta.LINE_ID;
            product.NODE_ID = _sta.NODE_ID;
            product.NODE_STATE = true;//工序设置为完成

            _listProduct.Add(product);

            //添加过程信息
            PROCESS process = new PROCESS();
            process.SetUpdate();//需要写入的数据
            process.MAC = product_sn.MAC;
            process.WORKER_ID = _sta.WORKER_ID;
            process.WORKER_NAME = _sta.WORKER_NAME;
            process.FLOW_ID = _sta.FLOW_ID;
            process.LINE_ID = _sta.LINE_ID;
            process.NODE_ID = _sta.NODE_ID;
            process.TEST_RESULT = "Y";
            process.STATION_ID = _sta.ID;//保存站位信息
            process.START_TIME = DateTime.Now;

            _listProcess.Add(process);

            AppendRichTextBox(string.Format("当前产品数量为：{0}", _listProduct.Count));

            //如果数量为20开始包装
            if (_listProduct.Count == SharedData.BOX_NUMBER)
            {
                PackingBox();//写过程信息和产品信息
            }

            SetFocusSN();
        }
        /// <summary>
        /// 获取所有的PRODUCT_SN和DEVICE_DATA的信息
        /// </summary>
        /// <param name="strSn"></param>
        private bool GetAllMessage(string strSn)
        {
            int year = 0;
            switch (strSn.Substring(10, 1))
            {
                case "A":
                    year = 2015;
                    break;
                case "B":
                    year = 2016;
                    break;
                case "C":
                    year = 2017;
                    break;
                case "D":
                    year = 2018;
                    break;
                case "E":
                    year = 2019;
                    break;
                case "F":
                    year = 2020;
                    break;
                case "G":
                    year = 2021;
                    break;
                case "H":
                    year = 2022;
                    break;
                case "I":
                    year = 2023;
                    break;
                case "J":
                    year = 2024;
                    break;
                case "K":
                    year = 2025;
                    break;
                default:
                    year = 2026;
                    break;
            }

            char cMonth = strSn[11];
            int month;
            switch (cMonth)
            {
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    month = int.Parse(strSn.Substring(11, 1));
                    break;
                case 'A':
                    month = 10;
                    break;         
                case 'B':
                    month = 11;
                    break;          
                case 'C':
                    month = 12;
                    break;
                default:
                    month = 0;
                    break;
            }

            int snNum = int.Parse(strSn.Substring(12, 6));

            //goto start;
            //判断包装数据是否已经存在
            BOX_MODEM boxW = new BOX_MODEM();
            boxW.SetWhere(string.Format(" BOX_NO=(SELECT FULL_BOX_SN FROM PRODUCT_SN WHERE SN_NUM={0} AND YEAR={1} AND MONTH={2})", snNum, year, month));
            var selectBox = MethodWcf.SelectBoxModemClient(boxW);
            if (selectBox.result)
            {
                AppendRichTextBox("已经装箱，请用模板打印，箱号为：" + selectBox.value[0].BOX_NO);

                #region 增加打印箱号的功能
                PrintBoxLabel(selectBox.value[0].BOX_NO, strSn);
                #endregion

                return false;
            }

            //start:

#if false
            #region use view

            string sqlSelectSn = string.Format(
                "SELECT * FROM View_ProductSn WHERE FULL_BOX_SN=(select FULL_BOX_SN from View_ProductSn where FULL_PRODUCT_SN='{0}') and MAC is not null and MAC<>''  order by FULL_PRODUCT_SN"
                , strSn);

            List<PRODUCT_SN> listProductSn = MethodWcf.SelectJsonClient<List<PRODUCT_SN>>(sqlSelectSn);

            if (listProductSn == null || listProductSn.Count == 0)
            {
                AppendRichTextBox("获取Product_sn 失败，在 GetAllMessage() 方法中");
                return false;
            }

            string sqlSelectDevice = "SELECT * FROM  Modem.dbo.CHANGE_DEVICE WHERE MACAddr in('";
            for (int i = 0; i < listProductSn.Count; i++)
            {
                sqlSelectDevice += listProductSn[i].MAC + "','";
            }
            sqlSelectDevice = sqlSelectDevice.TrimEnd(',', '\'') + "') order by SN";

            List<Device_Data> listDeviceData = MethodWcf.SelectJsonClient<List<Device_Data>>(sqlSelectDevice);

            if (listDeviceData == null || listDeviceData.Count == 0)
            {
                AppendRichTextBox("获取Device Data 数据失败，在GetAllMessage()中");
                return false;
            }

            _listData = listDeviceData;
            _listSn = listProductSn;

            #endregion

#else
            //查所有的SN
            PRODUCT_SN snW = new PRODUCT_SN();
            snW.SetWhere(string.Format(
                "BOX_SN=(SELECT BOX_SN from PRODUCT_SN where SN_NUM={0} AND YEAR={1} AND MONTH={2}) AND YEAR={1} AND MONTH={2} order by SN_NUM"
                , snNum
                , year
                , month));

            var selectSn = MethodWcf.SelectProductSnClient(snW);
            if (selectSn.result == false || selectSn.value.Count != SharedData.BOX_NUMBER)
            {
                AppendRichTextBox("获取SN信息失败，可能原因是此箱号中的SN没有分配完");
                return false;
            }

            //查所有的DEVICE
            Device_Data deviceW = new Device_Data();
            string sqlW = "MACAddr in('";
            for (int i = 0; i < selectSn.value.Count; i++)
            {
                sqlW += selectSn.value[i].MAC + "','";
            }
            sqlW = sqlW.TrimEnd(',', '\'') + "') order by SN";

            deviceW.SetWhere(sqlW);

            var selectDevice = MethodWcf.SelectDeviceDataClient(deviceW);
            if (selectDevice.result == false || selectDevice.value.Count != SharedData.BOX_NUMBER)
            {
                AppendRichTextBox("获取产品信息失败");
                return false;
            }

            _listData = selectDevice.value;
            _listSn = selectSn.value;
#endif


            //异步写本地记录
            WriteLocalLog(_listData, _listSn[0].FULL_BOX_SN);

            //写一条装箱数据
            BOX_MODEM box = new BOX_MODEM();
            box.SetUpdate();
            box.PRODUCT_CODE = _listData[0].ProductCode;
            box.BOX_NO = _listSn[0].FULL_BOX_SN;

            box.COUNT = SharedData.BOX_NUMBER;
            box.PON_TYPE = _listData[0].PONType;
            //给表赋值
            for (int i = 0; i < _listSn.Count; i++)
            {
                switch (i + 1)
                {
                    case 1:
                        box.PRO_NO_1 = _listData[i].SN;
                        box.DSNum_1 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_1 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 2:
                        box.PRO_NO_2 = _listData[i].SN;
                        box.DSNum_2 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_2 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 3:
                        box.PRO_NO_3 = _listData[i].SN;
                        box.DSNum_3 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_3 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 4:
                        box.PRO_NO_4 = _listData[i].SN;
                        box.DSNum_4 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_4 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 5:
                        box.PRO_NO_5 = _listData[i].SN;
                        box.DSNum_5 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_5 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 6:
                        box.PRO_NO_6 = _listData[i].SN;
                        box.DSNum_6 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_6 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 7:
                        box.PRO_NO_7 = _listData[i].SN;
                        box.DSNum_7 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_7 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 8:
                        box.PRO_NO_8 = _listData[i].SN;
                        box.DSNum_8 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_8 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 9:
                        box.PRO_NO_9 = _listData[i].SN;
                        box.DSNum_9 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_9 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 10:
                        box.PRO_NO_10 = _listData[i].SN;
                        box.DSNum_10 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_10 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 11:
                        box.PRO_NO_11 = _listData[i].SN;
                        box.DSNum_11 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_11 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 12:
                        box.PRO_NO_12 = _listData[i].SN;
                        box.DSNum_12 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_12 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 13:
                        box.PRO_NO_13 = _listData[i].SN;
                        box.DSNum_13 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_13 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 14:
                        box.PRO_NO_14 = _listData[i].SN;
                        box.DSNum_14 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_14 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 15:
                        box.PRO_NO_15 = _listData[i].SN;
                        box.DSNum_15 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_15 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 16:
                        box.PRO_NO_16 = _listData[i].SN;
                        box.DSNum_16 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_16 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 17:
                        box.PRO_NO_17 = _listData[i].SN;
                        box.DSNum_17 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_17 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 18:
                        box.PRO_NO_18 = _listData[i].SN;
                        box.DSNum_18 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_18 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 19:
                        box.PRO_NO_19 = _listData[i].SN;
                        box.DSNum_19 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_19 = _listData[i].DeviceSerialNumber1;
                        break;
                    case 20:
                        box.PRO_NO_20 = _listData[i].SN;
                        box.DSNum_20 = _listData[i].DeviceSerialNumber;
                        box.DSNumX_20 = _listData[i].DeviceSerialNumber1;
                        break;
                    default:
                        break;
                }
            }

            var insertBox = MethodWcf.InsertBoxModemClient(box);//插入包装数据
            if (insertBox.result == false)
            {
                AppendRichTextBox(string.Format("未能成功创建包装数据：[{0}]", insertBox.message));

                //清空链表数据
                ClearList();
                return false;
            }

            return true;
        }

        private void PrintBoxLabel(string boxNo,string sn)
        {
            if (MessageBox.Show(string.Format("是否重新打印箱号[{0}]的标签？", boxNo), "提示", MessageBoxButtons.YesNo) == DialogResult.No) return;

            Device_Data deviceW = new Device_Data();
            deviceW.SetWhere();
            deviceW.SN = sn;
            var selectDevice = MethodWcf.SelectDeviceDataClient(deviceW);
            if (selectDevice.result)
            {
                //获取配置数据
                if (_deviceType != selectDevice.value[0].DeviceType || _province != selectDevice.value[0].HW_PROVINCE_NAME)
                {
                    _btwPath = AppSetting.GetValue(string.Format("{0}_{1}_1", selectDevice.value[0].DeviceType, selectDevice.value[0].HW_PROVINCE_NAME));

                    if (string.IsNullOrEmpty(_btwPath)) _btwPath = AppSetting.GetValue(string.Format("{0}_1", selectDevice.value[0].DeviceType));
                }

                PrintLabel(boxNo);
            }

            //清空链表数据
            ClearList();

        }

        private void WriteLocalLog(List<Device_Data> listDevice, string boxSn, bool isOther = false)
        {

            //写产品数据到本地，按照省份区分
            string dirPath, fileName, strMsg = null;
            if (DateTime.Now.Hour >= 8 && DateTime.Now.Hour < 20)
            {
                dirPath = DATA_DIR + DateTime.Now.ToString("yyyyMMdd") + "_白班\\";
            }
            else if (DateTime.Now.Hour < 8)
            {
                dirPath = DATA_DIR + DateTime.Now.AddDays(-1).ToString("yyyyMMdd") + "_夜班\\";
            }
            else
            {
                dirPath = DATA_DIR + DateTime.Now.ToString("yyyyMMdd") + "_夜班\\";
            }

            if (isOther)
            {
                dirPath = DATA_DIR + DateTime.Now.ToString("yyyyMMdd") + "_特殊包装\\";
            }

            fileName = listDevice[0].ORDER_SN+ ".txt";

            //写打头的标题
            if (File.Exists(dirPath + fileName) == false)
            {
                string tital = "生产日期 \t品牌\t设备型号\t设备MAC\tSSID默认名称\tSSID默认密码\t管理IP\t登陆账号\t密码\t电压\t电流\t设备SN\t生产序列号\t箱号\t编译版本\r\n";
                LogHelper.WriteLog(dirPath, fileName, tital);
            }

            //编译版本查询
            string version = (from t in _listDeviceType
                              where t.DeviceType == listDevice[0].DeviceType && t.PROVINCE == listDevice[0].HW_PROVINCE_NAME
                              select t.BuildTime).FirstOrDefault();

            //兼容两种不同的数据需求
            for (int j = 0; j < listDevice.Count; j++)
            {
                strMsg += DateTime.Now + "\t"
                    + "友华\t"
                    + listDevice[j].DeviceType + "\t"
                    + listDevice[j].MACAddr + "\t"
                    + listDevice[j].WIFI_SSID + "\t"
                    + listDevice[j].WIFI_Password + "\t"
                    + listDevice[j].LanIP + "\t"
                    + listDevice[j].WedUser + "\t"
                    + listDevice[j].WedPassword + "\t"
                    + "12VDC\t"
                    + "1A\t"
                    + listDevice[j].DeviceSerialNumber + "\t"
                    + listDevice[j].SN + "\t"
                    + boxSn + "\t"
                    + version + "\r\n";
            }

            //写本地日志
            LogHelper.WriteLog(dirPath, fileName, strMsg);
        }

        private void PackingBox()
        {
            //显示箱号
            SetBoxNo(_listSn[0].FULL_BOX_SN);

            //打印箱号
            PrintLabel(_listSn[0].FULL_BOX_SN);

            //using transaction
            StringBuilder sqlBuf = new StringBuilder();
            sqlBuf.AppendLine(SharedData.SQL_TRANSCATION_START);

            //更新产品的箱号
            for (int j = 0; j < _listProduct.Count; j++)
            {
#region using transaction

                sqlBuf.AppendLine(ObjectToSQL.ObjectToUpdateSql(_listProduct[j]));
                _listProcess[j].END_TIME = DateTime.Now;
                sqlBuf.AppendLine(ObjectToSQL.ObjectToInsertSql(_listProcess[j]));
                continue;

#endregion

                //var updateProduct = MethodWcf.UpdateProductClient(_listProduct[j]);

                //if (updateProduct.result)
                //    AppendRichTextBox(string.Format("更新产品信息成功，MAC[{0}]", _listProduct[j].MAC));
                //else
                //    AppendRichTextBox(string.Format("更新产品信息失败，MAC[{0}]", _listProduct[j].MAC));

                ////写入过程信息
                //_listProcess[j].END_TIME = DateTime.Now;

                //var insertProcess = MethodWcf.InsertProcessClient(_listProcess[j]);
                //if (insertProcess.result == false)
                //{
                //    AppendRichTextBox(string.Format("插入过程信息[{0}]，MAC[{1}]", insertProcess.message, _listProcess[j].MAC));
                //}
                //else
                //{
                //    AppendRichTextBox(string.Format("插入过程信息[{0}]，MAC[{1}]", "成功", _listProcess[j].MAC));
                //}
            }

            sqlBuf.AppendLine(SharedData.SQL_TRANSCATION_END);
            int executeNum = Client.MethodWcf.ExecuteSQLClient(sqlBuf.ToString());

            if (executeNum <= 0)
            {
                AppendRichTextBox("写入数据失败");
            }
            else
            {
                AppendRichTextBox($"写入数据成功，数据量：{executeNum}");
            }

            //清空链表数据
            ClearList();
        }

        //异步设置mac地址能不能输入
        private void SetTextBoxSnEnable(bool enabled = true)
        {
            if (this.textBoxProductSN.InvokeRequired)
            {
                Action<bool> d = new Action<bool>(SetTextBoxSnEnable);
                this.Invoke(d, new object[] { enabled });
            }
            else
            {
                this.textBoxProductSN.Enabled = enabled;
                this.buttonCannel.Enabled = enabled;
            }
        }

        private void PrintLabel(string boxNo)
        {
            if (string.IsNullOrEmpty(_btwPath) || File.Exists(_btwPath) == false)
            {
                AppendRichTextBox("未能获得打标文件，打印失败！请打开打标软件手动打印！");
                MessageBox.Show("未能获得打标文件，打印失败！请打开打标软件手动打印！");
                return;
            }

            if (string.IsNullOrEmpty(boxNo) || string.IsNullOrEmpty(_btwQuery))
            {
                MessageBox.Show("箱号或查询代码为空，打印失败");
                AppendRichTextBox("箱号或查询代码为空，打印失败");
                return;
            }

            AppendRichTextBox("开始打印标签……");
            Engine bt = new Engine();

            bt.Start();
            LabelFormatDocument btFormat = bt.Documents.Open(_btwPath);
            btFormat.DatabaseConnections.QueryPrompts[_btwQuery].Value = boxNo;
            btFormat.PrintSetup.IdenticalCopiesOfLabel = _btwCopies;

            btFormat.Print("标签软件", 2000);


            btFormat.PrintSetup.Cache.FlushInterval = CacheFlushInterval.PerSession;
            btFormat.Close(SaveOptions.DoNotSaveChanges);
            bt.Stop();

            AppendRichTextBox("标签打印完成");
        }

        //取消装箱
        private void ButtonCannel_Click(object sender, EventArgs e)
        {
            ClearList();
            MessageBox.Show("取消装箱成功");
        }
        /// <summary>
        /// 清空产品和过程的链表信息
        /// </summary>
        private void ClearList()
        {
            //初始化信息
            _listSn.Clear();
            _listData.Clear();
            _listProcess.Clear();
            _listProduct.Clear();
            _lastSnNum = 0;//清空lastSnNum判断
        }

        //将信息检查信息窗口
        private void AppendRichTextBox(string value)
        {
            if (this.richTextBoxMsg.InvokeRequired)
            {
                Action<string> d = new Action<string>(AppendRichTextBox);
                Invoke(d, new object[] { value });
            }
            else
            {
                if (value == null) return;
                if (this.richTextBoxMsg.TextLength >= 5000)
                    this.richTextBoxMsg.Clear();
                this.richTextBoxMsg.AppendText(value);
                this.richTextBoxMsg.AppendText("\n");
            }
        }

        /// <summary>
        /// 将焦点移动到textSN上，true为装箱完毕操作，false为过程中的操作
        /// </summary>
        /// <param name="flag"></param>
        private void SetFocusSN(bool flag = false)
        {
            if (this.textBoxProductSN.InvokeRequired)
            {
                Action<bool> d = new Action<bool>(SetFocusSN);
                Invoke(d, new object[] { flag });
            }
            else
            {
                SetTextBoxSnEnable();
                this.textBoxProductSN.Clear();//清空MAC地址
                this.textBoxProductSN.Focus();
            }
        }

        //设置箱号显示在输入窗口下方
        private void SetBoxNo(string boxNo)
        {
            if (this.textBoxNo.InvokeRequired)
            {
                Action<string> d = new Action<string>(SetBoxNo);
                this.Invoke(d, new object[] { boxNo });
            }
            else
            {
                this.textBoxNo.Text = boxNo;
            }
        }

        //关闭此窗口打开主窗口
        private void FormBox_FormClosed(object sender, FormClosedEventArgs e)
        {
            _formSta.Show();//窗体显示
            _formSta.WindowState = FormWindowState.Normal;  //窗体状态默认大小  
            _formSta.Activate(); //激活窗体给予焦点
        }

        //滚动窗口
        private void richTextBoxMsg_TextChanged(object sender, EventArgs e)
        {
            this.richTextBoxMsg.SelectionStart = this.richTextBoxMsg.Text.Length;
            this.richTextBoxMsg.ScrollToCaret();
        }

        private void ClearMac()
        {
            string mac = this.textBoxMac.Text.Trim();

            //判断是否包装了

            int ret = MethodWcf.ExecuteSQLClient(string.Format("DECLARE	@message varchar(200)  EXEC	[dbo].[Proc_MacResetSn] 		@mac = N'{0}',@message = @message OUTPUT", mac));

            if (ret < 0) MessageBox.Show("清除SN失败，可能原因是产品已经装箱");
            else MessageBox.Show("清除SN成功");

        }

        private void buttonClearSn_Click(object sender, EventArgs e)
        {
            ClearMac();
            this.textBoxMac.Clear();
            this.textBoxMac.Focus();
        }

#region 自动缩放

        private float X = 0.0f;
        private float Y = 0.0f;

        private void setTag(Control cons)
        {
            foreach (Control con in cons.Controls)
            {
                con.Tag = con.Width + ":" + con.Height + ":" + con.Top + ":" + con.Left + ":" + con.Font.Size;
                if (con.Controls.Count > 0)
                {
                    setTag(con);
                }
            }
        }
        private void setControls(float newx, float newy, Control cons)
        {
            foreach (Control con in cons.Controls)
            {
                String[] mytags = con.Tag.ToString().Split(new char[] { ':' });
                float a = Convert.ToSingle(mytags[0]) * newx;
                con.Width = (int)a;
                a = Convert.ToSingle(mytags[1]) * newy;
                con.Height = (int)a;
                a = Convert.ToSingle(mytags[2]) * newy;
                con.Top = (int)a;
                a = Convert.ToSingle(mytags[3]) * newx;
                con.Left = (int)a;
                Single currectsize = Convert.ToSingle(mytags[4]) * newy;
                con.Font = new Font(con.Font.Name, currectsize, con.Font.Style, con.Font.Unit);
                if (con.Controls.Count > 0)
                {
                    setControls(newx, newy, con);
                }
            }
        }

        private void Form_Resize(object sender, EventArgs e)
        {
            float newX = this.Width / X;
            float newY = this.Height / Y;

            setControls(newX, newY, this);
            //this.Text = this.Width.ToString() + "*" + this.Height.ToString();
        }


#endregion

        private void FormBox_Load(object sender, EventArgs e)
        {
            Device_Type typeW = new Device_Type();
            var selectType = MethodWcf.SelectDeviceTypeClient(typeW);
            if (selectType.result) _listDeviceType = selectType.value;

            //等比例缩放
            X = this.Width;
            Y = this.Height;

            setTag(this);

            this.Resize += new EventHandler(Form_Resize);
        }

#region 特殊装箱工具
        private void richTextBoxMsg_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (groupBox4.Visible == false)
            {
                PasswordInput pass = new PasswordInput();
                if (pass.ShowDialog() == DialogResult.OK)
                {
                    groupBox4.Visible = true; groupBox2.Visible = true;
                }
            }
            else { groupBox4.Visible = false; groupBox2.Visible = false; }
        }

        private void textBoxOtherSn_KeyPress(object sender, KeyPressEventArgs e)
        {
            //只能输入16进制数字和回车符号'\r'或者'\n'，MAC地址中的字符只能位0-9,A~F
            if (e.KeyChar == '\n' || e.KeyChar == '\r')
            {
                Action actStart = new Action(PackingOtherSn);//异步装箱操作，让输出完整
                actStart.BeginInvoke(null, null);
                e.Handled = true;
            }
            else if ((e.KeyChar >= 'a' && e.KeyChar <= 'f')
                || (e.KeyChar >= 'A' && e.KeyChar <= 'F')
                || (e.KeyChar >= '0' && e.KeyChar <= '9')
                || (e.KeyChar == 8))
            {
                //判断是否位16进制字符，将小写全部转为大写
                e.Handled = false;
            }
            else
            {
                MessageBox.Show("只能输入数字和A-F");
                e.Handled = true;
            }
        }


        private List<Device_Data> _listOtherDevice = new List<Device_Data>();
        private void PackingOtherSn()
        {
            string strSn = this.textBoxOtherSn.Text.Trim();

            //判断SN是否为18位
            if (string.IsNullOrEmpty(strSn) || (strSn.Length != 18 && strSn.Length != 12))
            {
                MessageBox.Show("SN不为18位字符串，或MAC不为12位");
                FocusOtherSn();
                return;
            }

            //获取ListDeviceData的数据
            Device_Data deviceW = new Device_Data();
            deviceW.SetWhere();
            if (strSn.Length == 12)
                deviceW.MACAddr = strSn;
            else
                deviceW.SN = strSn;

            var selectDevice = MethodWcf.SelectDeviceDataClient(deviceW);
            if (selectDevice.result)
            {
                strSn = selectDevice.value[0].SN;
            }

            var tempDev = _listOtherDevice.FirstOrDefault(a => a.SN == strSn);
            if (tempDev != null)
            {
                AppendRichTextBox($"SN[{strSn}]已经扫描");
                FocusOtherSn();
                return;
            }

#region 判断SN是否可以包装 18.8.16注销
            //判断SN是否可以包装
            StartRequest req = new StartRequest()
            {
                PRODUCT_SN = strSn,
                STATION_MAC = _sta.MAC
            };

            AppendRichTextBox("申请包装……");
            var canStart = MethodWcf.CanStartClient(req);

            AppendRichTextBox(string.Format("申请结果：{0}，SN：{1}", canStart.message, strSn));
            if (canStart.result == false) { FocusOtherSn(); return; }
#endregion


            if (selectDevice.result)
            {
                if (_listOtherDevice.Count != 0)
                {
                    //判断是否同一个省份同一种类型
                    if (selectDevice.value[0].HW_PROVINCE_NAME != _listOtherDevice[0].HW_PROVINCE_NAME || selectDevice.value[0].DeviceType != _listOtherDevice[0].DeviceType)
                    {
                        AppendRichTextBox("扫入产品省份或类型不匹配，请检查");
                        MessageBox.Show("扫入产品省份或类型不匹配，请检查");
                        FocusOtherSn();
                        return;
                    }
                }

                AppendRichTextBox(string.Format("获取DEVICE数据成功,SN:[{0}]", strSn));
                _listOtherDevice.Add(selectDevice.value[0]);

                AppendRichTextBox(string.Format("当前产品数量为：{0}",_listOtherDevice.Count));
            }
            else
            {
                AppendRichTextBox("获取DEVICE的数据错误");
            }

            FocusOtherSn();
        }

        private void FocusOtherSn()
        {
            if (this.InvokeRequired)
            {
                Action d = new Action(FocusOtherSn);
                Invoke(d);
            }
            else
            {
                this.textBoxOtherSn.Clear();
                this.textBoxOtherSn.Focus();
            }
        }


        private void buttonChannel_Click(object sender, EventArgs e)
        {
            _listOtherDevice.Clear();
            MessageBox.Show("清除包装数据成功");
        }

        private void buttonSaveOther_Click(object sender, EventArgs e)
        {
            if (_listOtherDevice.Count == 0 || _listOtherDevice.Count > 20)
            {
                AppendRichTextBox("没有产品，或产品数量大于20");
                return;
            }

            //获取箱号
            string boxSn = MethodWcf.ExecuteReturnSQLClient(string.Format("DECLARE	@box_sn varchar(50), 		@message varchar(200)  EXEC	 [dbo].[Proc_GetOtherBoxSn] 		@mac = N'{0}', 	@box_sn = @box_sn OUTPUT, @message = @message OUTPUT  SELECT	@box_sn as N'@box_sn'", _listOtherDevice[0].MACAddr));

            SetControlText(textBoxOtherBoxSn, boxSn);

            //写一条装箱数据
            BOX_MODEM box = new BOX_MODEM();
            box.SetWhere();
            box.BOX_NO = boxSn;
            box.SetUpdate();
            box.PRODUCT_CODE = _listOtherDevice[0].ProductCode;

            box.COUNT = _listOtherDevice.Count;
            box.PON_TYPE = _listOtherDevice[0].PONType;

            PRODUCT proW = new PRODUCT();
            //给表赋值
            for (int i = 0; i < _listOtherDevice.Count; i++)
            {
                //更新product到20072
                proW.Clear();
                proW.SetWhere();
                proW.MAC = _listOtherDevice[i].MACAddr;
                proW.SetUpdate();
                proW.NODE_ID = _sta.NODE_ID;
                proW.LINE_ID = _sta.LINE_ID;
                proW.FLOW_ID = _sta.FLOW_ID;
                MethodWcf.UpdateProductClient(proW);

                switch (i + 1)
                {
                    case 1:
                        box.PRO_NO_1 = _listOtherDevice[i].SN;
                        box.DSNum_1 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_1 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 2:
                        box.PRO_NO_2 = _listOtherDevice[i].SN;
                        box.DSNum_2 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_2 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 3:
                        box.PRO_NO_3 = _listOtherDevice[i].SN;
                        box.DSNum_3 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_3 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 4:
                        box.PRO_NO_4 = _listOtherDevice[i].SN;
                        box.DSNum_4 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_4 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 5:
                        box.PRO_NO_5 = _listOtherDevice[i].SN;
                        box.DSNum_5 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_5 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 6:
                        box.PRO_NO_6 = _listOtherDevice[i].SN;
                        box.DSNum_6 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_6 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 7:
                        box.PRO_NO_7 = _listOtherDevice[i].SN;
                        box.DSNum_7 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_7 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 8:
                        box.PRO_NO_8 = _listOtherDevice[i].SN;
                        box.DSNum_8 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_8 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 9:
                        box.PRO_NO_9 = _listOtherDevice[i].SN;
                        box.DSNum_9 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_9 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 10:
                        box.PRO_NO_10 = _listOtherDevice[i].SN;
                        box.DSNum_10 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_10 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 11:
                        box.PRO_NO_11 = _listOtherDevice[i].SN;
                        box.DSNum_11 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_11 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 12:
                        box.PRO_NO_12 = _listOtherDevice[i].SN;
                        box.DSNum_12 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_12 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 13:
                        box.PRO_NO_13 = _listOtherDevice[i].SN;
                        box.DSNum_13 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_13 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 14:
                        box.PRO_NO_14 = _listOtherDevice[i].SN;
                        box.DSNum_14 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_14 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 15:
                        box.PRO_NO_15 = _listOtherDevice[i].SN;
                        box.DSNum_15 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_15 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 16:
                        box.PRO_NO_16 = _listOtherDevice[i].SN;
                        box.DSNum_16 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_16 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 17:
                        box.PRO_NO_17 = _listOtherDevice[i].SN;
                        box.DSNum_17 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_17 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 18:
                        box.PRO_NO_18 = _listOtherDevice[i].SN;
                        box.DSNum_18 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_18 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 19:
                        box.PRO_NO_19 = _listOtherDevice[i].SN;
                        box.DSNum_19 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_19 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    case 20:
                        box.PRO_NO_20 = _listOtherDevice[i].SN;
                        box.DSNum_20 = _listOtherDevice[i].DeviceSerialNumber;
                        box.DSNumX_20 = _listOtherDevice[i].DeviceSerialNumber1;
                        break;
                    default:
                        break;
                }
            }

            var updateBox = MethodWcf.UpdateBoxModemClient(box);//插入包装数据
            if (updateBox.result == false)
            {
                AppendRichTextBox(string.Format("未能成功创建包装数据：[{0}]", updateBox.message));
            }
            else
            {
                AppendRichTextBox(string.Format("包装成功"));
                //PrintLabel(boxSn);
                //生产本地数据
                WriteLocalLog(_listOtherDevice, boxSn, true);
            }

            _listOtherDevice.Clear();
        }

        private void SetControlText(Control con, string text)
        {
            if (this.InvokeRequired)
            {
                Action<Control, string> d = new Action<Control, string>(SetControlText);
                Invoke(d, con, text);
            }
            else
            {
                con.Text = text;
            }
        }

#endregion

        ////重新打印外箱标签
        //private void button1_Click(object sender, EventArgs e)
        //{
        //    //return;
        //    string boxSn = this.textBoxNo.Text;
        //    if (string.IsNullOrEmpty(boxSn) == false)
        //    {
        //        PrintLabel(boxSn);
        //    }
        //}
    }
}
